package com.example.scaffold_demo.http.request;

import android.util.Log;

import com.example.httplibrary.cache.CacheManager;
import com.example.httplibrary.cache.CacheType;
import com.example.httplibrary.jwt.DBWebSignature;

import com.example.scaffold_demo.BaseApplication;
import com.example.scaffold_demo.common.Constant;
import com.example.scaffold_demo.utils.SPUtils;
import com.example.scaffold_demo.utils.StringUtil;
import com.google.gson.Gson;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;


/**
 * @author 李巷阳
 * @version V1.0
 * @Description: (用一句话描述该文件做什么)
 * @date 2018/6/6
 */
public class RequestInterceptor implements Interceptor {
    private String access_token;

    @Override
    public Response intercept(Chain chain) throws IOException {
        // 请求的request
        Request request = chain.request();
        // 获取 access_token
        access_token = getAccessToken();
        // 初始化存储本地的缓存文件key
        String cacheKey = request.url().url().toString() + "&access_token" + access_token;
        try {
            if (request.method().equals("GET")) {
                request = addGetParams(request);
            } else if (request.method().equals("POST")) {
                request = addPostParams(request);
            } else if (request.method().equals("DELETE")) {
                request = addGetParams(request);
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }

        // 创建cache去请求头
        String cacheHead = request.header("cache");
        // cacheHead 获取 ApiService是否设置需要缓存策略
        if ("true".equals(cacheHead)) {
            return toCacheHttpRequest(chain, request, cacheKey);
        } else {
            return chain.proceed(request);
        }


    }


    //get请求 添加公共参数 签名
    private Request addGetParams(Request request) throws MalformedURLException, NoSuchAlgorithmException, InvalidKeyException {
//        String uid = getUid();

//        if (EnvirUtil.isDebug()) {     // 没有debug接口，去掉if语句分支
        HttpUrl httpUrl = request.url()
                .newBuilder()
                //token
                .addQueryParameter("access_token", access_token)
                //版本号 数字  34
                .addQueryParameter(Constant.APP_VERSION_CODE, String.valueOf(StringUtil.getVersionCode(BaseApplication.getContext())))
                //平台
                .addQueryParameter(Constant.PLATFORM, Constant.ANDROID)
                //渠道
                .addQueryParameter(Constant.CHANNEL, StringUtil.getAppChannelName(BaseApplication.getContext(), "UMENG_CHANNEL"))
                //版本名
                .addQueryParameter(Constant.APP_VERSION_NAME, String.valueOf(StringUtil.getVerName(BaseApplication.getContext())))
                //版本名
                .addQueryParameter(Constant.VERSION_NAME, String.valueOf(StringUtil.getVerName(BaseApplication.getContext())))
                //设备号
                .addQueryParameter(Constant.DEVICE_ID, StringUtil.getDeviceIdUniqueIdentifier(BaseApplication.getContext()))
                //时间戳
                .addQueryParameter(Constant.VISIT_TIME_TIMESTAMP, getTimestamp())
                .build();

        String httpurl_str = httpUrl.toString();
        String[] path_arr = httpurl_str.split("\\?");
        String host = path_arr[0];
        String parameter = "";
        for (int i = 1; i < path_arr.length; i++) {
            parameter += path_arr[i];
            if (i != path_arr.length - 1) {
                parameter += "?";
            }
        }

        if (parameter != null) {
            Map parameter_map = new HashMap();
            String[] parameter_arr = parameter.split("&");
            if (parameter_arr != null && parameter_arr.length > 0) {
                for (int i = 0; i < parameter_arr.length; i++) {
                    int index = parameter_arr[i].indexOf('=');
                    //添加参数
                    parameter_map.put(parameter_arr[i].substring(0, index), parameter_arr[i].substring((index + 1)));
                }
            }
            Gson gson = new Gson();
            String parameter_json = gson.toJson(parameter_map);
            Log.e(Constant.LOG_NETWORK_REQUEST,"get请求url-->" +host);
            Log.e(Constant.LOG_NETWORK_REQUEST,"get请求参数-->" +parameter_json);
            String data = DBWebSignature.getEncryption(parameter_json);
            String path = host + "?data=" + data;
            Log.e(Constant.LOG_NETWORK_REQUEST,"get请求pash-->" +path);

            URL url = new URL(path);
            request = getRequest(request, url);
            return request;
        }
        request = getRequest(request, new URL(httpurl_str));
        return request;
//        } else {
//            //添加参数
//            HttpUrl newHttpUrl = request.url().newBuilder()
//                    .addQueryParameter(Constant.VISIT_TIME_TIMESTAMP, getTimestamp())
//                    .addQueryParameter(Constant.ACCESS_TOKEN, access_token)
//                    .addQueryParameter(Constant.APP_VERSION_CODE, String.valueOf(APKVersionCodeUtils.getVersionCode(AppApplication.getContext())))
//                    .addQueryParameter(Constant.PLATFORM, Constant.ANDROID)
//                    .addQueryParameter(Constant.APP_VERSION_NAME,String.valueOf(APKVersionCodeUtils.getVerName(AppApplication.getContext())))
//                    .addQueryParameter("__debug__", "1").build();
//            request = request.newBuilder().url(newHttpUrl).build();
//
//
//        }
//        return request;
    }


    //post 添加签名和公共参数
    private Request addPostParams(Request request) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
//        String uid = getUid();

        if (request.body() instanceof FormBody) {
            FormBody.Builder bodyBuilder = new FormBody.Builder();
            FormBody formBody = (FormBody) request.body();

//            if (true) { 没有debug接口，去掉if语句分支


            Map map = new HashMap();

            //把原来的参数添加到新的构造器，（因为没找到直接添加，所以就new新的）
            for (int i = 0; i < formBody.size(); i++) {
                map.put(formBody.encodedName(i), formBody.value(i));
            }
            map.put(Constant.ACCESS_TOKEN, access_token);
            map.put(Constant.APP_VERSION_CODE, String.valueOf(StringUtil.getVersionCode(BaseApplication.getContext())));
            map.put(Constant.APP_VERSION_NAME, String.valueOf(StringUtil.getVerName(BaseApplication.getContext())));
            map.put(Constant.VERSION_NAME, String.valueOf(StringUtil.getVerName(BaseApplication.getContext())));
            map.put(Constant.PLATFORM, Constant.ANDROID);
            map.put(Constant.CHANNEL, StringUtil.getAppChannelName(BaseApplication.getContext(), "UMENG_CHANNEL"));
            map.put(Constant.DEVICE_ID, StringUtil.getDeviceIdUniqueIdentifier(BaseApplication.getContext()));
            map.put(Constant.VISIT_TIME_TIMESTAMP, getTimestamp());

            Gson gson = new Gson();
            String parameter = gson.toJson(map);

//            LogUtil.e(Constant.LOG_NETWORK_REQUEST,"post请求url-->" +request.url());
//            LogUtil.e(Constant.LOG_NETWORK_REQUEST,"post请求参数-->" +parameter);
            String data = DBWebSignature.getEncryption(parameter);
            bodyBuilder.add("data", data);
            request = postRequest(request, bodyBuilder);


//            } else {
//
//                HttpUrl old_url = request.url();
//                String old_url_str = old_url.toString();
//                String new_url_str = old_url_str + "?__debug__=1";
//                request = request.newBuilder().url(new_url_str).build();
//                //把原来的参数添加到新的构造器，（因为没找到直接添加，所以就new新的）
//                for (int i = 0; i < formBody.size(); i++) {
//                    bodyBuilder.addEncoded(formBody.encodedName(i), formBody.encodedValue(i));
//                }
//
//                bodyBuilder.addEncoded(Constant.VISIT_TIME_TIMESTAMP, getTimestamp());
//                bodyBuilder.addEncoded(Constant.ACCESS_TOKEN, access_token);
//                bodyBuilder.addEncoded(Constant.APP_VERSION_CODE, String.valueOf(APKVersionCodeUtils.getVersionCode(AppApplication.getContext())));
//                bodyBuilder.addEncoded(Constant.APP_VERSION_NAME, String.valueOf(APKVersionCodeUtils.getVerName(AppApplication.getContext())));
//                bodyBuilder.addEncoded(Constant.PLATFORM, Constant.ANDROID);
//
//                request = postRequest(request, bodyBuilder);
//            }

        }
        return request;
    }

    /**
     * 添加POST头部信息
     *
     * @param request
     * @param bodyBuilder
     * @return
     */
    private Request postRequest(Request request, FormBody.Builder bodyBuilder) {
        request = request.newBuilder().post(bodyBuilder.build()).
                addHeader("o", "Android").// 操作系统
                addHeader("s", String.valueOf(StringUtil.getBuildLevel())).// 操作系统版本
                addHeader("sv", StringUtil.getBuildVersion()).// 操作系统版本号
                addHeader("a", StringUtil.getVersionCode(BaseApplication.getContext())).// build号 VersionCode
                addHeader("n", StringUtil.getVersionName(BaseApplication.getContext())).// 版本号 VersionName
                addHeader("d", StringUtil.getStaticMacAddress(BaseApplication.getContext())).// MAC 地址
                addHeader("dd", StringUtil.getDeviceIdUniqueIdentifier(BaseApplication.getContext())).// 设备号
                addHeader("w", String.valueOf(StringUtil.deviceWidth(BaseApplication.getContext()))).// 屏幕宽度
                addHeader("h", String.valueOf(StringUtil.deviceHeight(BaseApplication.getContext()))).// 屏幕高度
                addHeader("c", StringUtil.getAppChannelName(BaseApplication.getContext(), "UMENG_CHANNEL")).// 渠道
                addHeader("lang", "zh-Hans").// 语言
                addHeader("m", StringUtil.getPhoneModel()).// 型号
                addHeader("ma", StringUtil.getPhoneBrand()).// 厂商
                addHeader("l", StringUtil.getNetStateType(BaseApplication.getContext())).// 网络状态
//                addHeader("z", DeviceUtils.getTimeZone()).// 时区
                addHeader("nd",StringUtil.getDeviceIdUniqueIdentifierNew(BaseApplication.getContext())).
                build();

        return request;
    }

    /**
     * 添加GET方式头部信息
     *
     * @param request
     * @param url
     * @return
     */
    private Request getRequest(Request request, URL url) {
        request = request.newBuilder().url(url).
                addHeader("o", "Android").// 操作系统
                addHeader("s", String.valueOf(StringUtil.getBuildLevel())).// 操作系统版本
                addHeader("sv", StringUtil.getBuildVersion()).// 操作系统版本号
                addHeader("a", StringUtil.getVersionCode(BaseApplication.getContext())).// build号 VersionCode
                addHeader("n", StringUtil.getVersionName(BaseApplication.getContext())).// 版本号 VersionName
                addHeader("d", StringUtil.getStaticMacAddress(BaseApplication.getContext())).// MAC 地址
                addHeader("dd", StringUtil.getDeviceIdUniqueIdentifier(BaseApplication.getContext())).// 设备号
                addHeader("w", String.valueOf(StringUtil.deviceWidth(BaseApplication.getContext()))).// 屏幕宽度
                addHeader("h", String.valueOf(StringUtil.deviceHeight(BaseApplication.getContext()))).// 屏幕高度
                addHeader("c", StringUtil.getAppChannelName(BaseApplication.getContext(), "UMENG_CHANNEL")).// 渠道
                addHeader("lang", "zh-Hans").// 语言
                addHeader("m", StringUtil.getPhoneModel()).// 型号
                addHeader("ma", StringUtil.getPhoneBrand()).// 厂商
                addHeader("l", StringUtil.getNetStateType(BaseApplication.getContext())).// 网络状态
//                addHeader("z", DeviceUtils.getTimeZone()).// 时区
                addHeader("nd",StringUtil.getDeviceIdUniqueIdentifierNew(BaseApplication.getContext())).
                build();

        return request;
    }

    private String getTimestamp() {
        return StringUtil.getCurrentDislodgeLocalError() + "";
    }


    private String getAccessToken() {
//        String mAuth_key = ""UserInfoUtils.getAuth_key(AppApplication.getContext())"";
        String mAuth_key = (String) SPUtils.get(Constant.ACCESS_TOKEN,"");
        if(mAuth_key!=null){
            return mAuth_key;
        }
        return "";
    }


    //--------------------------------------cache  start-------------------------------------------------

    /**
     * 使用缓存策略访问数据
     *
     * @param chain
     * @param request
     * @param cacheKey
     * @return
     * @throws IOException
     */
    private Response toCacheHttpRequest(Chain chain, Request request, String cacheKey) throws IOException {
        // 获取当前时间戳
        long oldnow = System.currentTimeMillis();
        String responStr = null;
        try {
            // 访问网络,获取返回值Response
            Response response = chain.proceed(request);
            // 只有在网络请求返回成功之后，才进行缓存处理，否则，404存进缓存，岂不笑话
            if (response.isSuccessful()) {
                // 获取返回值
                ResponseBody responseBody = response.body();
                if (responseBody != null) {
                    responStr = responseBody.string();
                    if (responStr == null) {
                        responStr = "";
                    }
                    // 存储本地
                    CacheManager.getInstance(BaseApplication.getContext()).setCache(CacheManager.encryptMD5(cacheKey), responStr);//存缓存，以链接+参数进行MD5编码为KEY存
                    Log.i("HttpRetrofit", "--> responStr:" + responStr);
                    Log.i("HttpRetrofit", "--> Push Cache:" + cacheKey + " :Success");
                }
                // 创建新的Response.
                return setResetResponse(response, responStr);
            } else {
                // 正常请求
                return chain.proceed(request);
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 发生异常了，我这里就开始去缓存，但是有可能没有缓存，那么久需要丢给下一轮处理了
            Response response = getCacheResponse(request, oldnow, cacheKey);
            // 如果没有缓存,则正常请求
            if (response == null) {
                // 正常请求
                return chain.proceed(request);
            } else {
                return response;
            }
        }
    }

    /**
     * 模拟网络请求,获取本地缓存
     *
     * @param request
     * @param oldNow
     * @param cacheKey
     * @return
     */
    private Response getCacheResponse(Request request, long oldNow, String cacheKey) {
        Log.i("HttpRetrofit", "--> Try to Get Cache   --------");
        String url = cacheKey;
        String cacheStr = CacheManager.getInstance(BaseApplication.getContext()).getCache(CacheManager.encryptMD5(url));//取缓存，以链接+参数进行MD5编码为KEY取
        if (cacheStr == null) {
            Log.i("HttpRetrofit", "<-- Get Cache Failure ---------");
            return null;
        }
        Response response = new Response.Builder()
                .code(200)
                .body(ResponseBody.create(null, cacheStr))
                .request(request)
                .message(CacheType.DISK_CACHE)// 从内存还是从缓存中获取
                .protocol(Protocol.HTTP_1_0)
                .build();
        long useTime = System.currentTimeMillis() - oldNow;
        Log.i("HttpRetrofit", "<-- Get Cache: " + response.code() + " " + response.message() + " " + url + " (" + useTime + "ms)");
        Log.i("HttpRetrofit", cacheStr + "");
        return response;
    }

    /**
     * 原因为OkHttp请求回调中response.body().string()只能有效调用一次，而使用了两次：
     * 就会报okhttp的java.lang.IllegalStateException: closed错误.
     * 所以我们在这边重新创建和重置Response对象.
     *
     * @param response
     * @param body
     * @return
     */
    private Response setResetResponse(Response response, String body) {
        ResponseBody responseBody = response.body();
        return new Response.Builder()
                .code(response.code())
                .body(ResponseBody.create(responseBody == null ? null : responseBody.contentType(), body))
                .request(response.request())
                .message(response.message())
                .protocol(response.protocol())
                .build();
    }


    //--------------------------------------cache  end-------------------------------------------------


}
